iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
自我挑戰組

自學vue~點亮Roadmap過程系列 第 20

vue3鍊成術第二十天-列表渲染(1)

  • 分享至 

  • xImage
  •  

列表渲染(1)

v-for

我們可以使用 v-for 指令基於一個數組來渲染一個列表。v-for 指令的值需要使用 item in items 形式的特殊語法,其中 items 是源數據的數組,而 item 是迭代項的別名:

const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
<li v-for="item in items">
  {{ item.message }}
</li>

在 v-for 塊中可以完整地訪問父作用域內的屬性和變量。v-for 也支持使用可選的第二個參數表示當前項的位置索引。

const parentMessage = ref('Parent')
const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
<li v-for="(item, index) in items">
  {{ parentMessage }} - {{ index }} - {{ item.message }}
</li>

https://ithelp.ithome.com.tw/upload/images/20241003/20169210PrBPAEmPVN.png

v-for 變量的作用域和下面的 JavaScript 代碼很類似:

const parentMessage = 'Parent'
const items = [
  /* ... */
]

items.forEach((item, index) => {
  // 可以訪問外層的 `parentMessage`
  // 而 `item` 和 `index` 只在這個作用域可用
  console.log(parentMessage, item.message, index)
})

注意 v-for 是如何對應 forEach 回調的函數簽名的。實際上,你也可以在定義 v-for 的變量別名時使用解構,和解構函數參數類似:

<li v-for="{ message } in items">
  {{ message }}
</li>

<!-- 有 index 索引時 -->
<li v-for="({ message }, index) in items">
  {{ message }} {{ index }}
</li>

對於多層嵌套的 v-for,作用域的工作方式和函數的作用域很類似。每個 v-for 作用域都可以訪問到父級作用域:

<li v-for="item in items">
  <span v-for="childItem in item.children">
    {{ item.message }} {{ childItem }}
  </span>
</li>

你也可以使用 of 作為分隔符來替代 in,這更接近 JavaScript 的迭代器語法:

<div v-for="item of items"></div>

v-for 與對象

你也可以使用 v-for 來遍歷一個對象的所有屬性。遍歷的順序會基於對該對象調用 Object.keys() 的返回值來決定。

const myObject = reactive({
  title: 'How to do lists in Vue',
  author: 'Jane Doe',
  publishedAt: '2016-04-10'
})
<ul>
  <li v-for="value in myObject">
    {{ value }}
  </li>
</ul>

可以通過提供第二個參數表示屬性名 (例如 key):

<li v-for="(value, key) in myObject">
  {{ key }}: {{ value }}
</li>

第三個參數表示位置索引:

<li v-for="(value, key, index) in myObject">
  {{ index }}. {{ key }}: {{ value }}
</li>

在 v-for 裡使用範圍值

v-for 可以直接接受一個整數值。在這種用例中,會將該模板基於 1...n 的取值範圍重複多次。

<span v-for="n in 10">{{ n }}</span>

注意此處 n 的初值是從 1 開始而非 0。

template上的 v-for

與模板上的 v-if 類似,你也可以在 template 標籤上使用 v-for 來渲染一個包含多個元素的塊。例如:

<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

v-for 與 v-if

注意!!!

同時使用 v-if 和 v-for 是不推薦的,因為這樣二者的優先級不明顯。

當它們同時存在於一個節點上時,v-if 比 v-for 的優先級更高。這意味著 v-if 的條件將無法訪問到 v-for 作用域內定義的變量別名:

<!--
 這會拋出一個錯誤,因為屬性 todo 此時
 沒有在該實例上定義
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo.name }}
</li>

在外先封装一層 template 再在其上使用 v-for 可以解決這個問題 (這也更加明顯易讀):

<template v-for="todo in todos">
  <li v-if="!todo.isComplete">
    {{ todo.name }}
  </li>
</template>

上一篇
vue3鍊成術第十九天-Class 與 Style 綁定(2)
下一篇
vue3鍊成術第二十一天-列表渲染(2)
系列文
自學vue~點亮Roadmap過程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言